package com.powernode.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.domain.SysUser;
import com.powernode.domain.SysUserRole;
import com.powernode.mapper.SysUserMapper;
import com.powernode.mapper.SysUserRoleMapper;
import com.powernode.service.SysUserRoleService;
import com.powernode.service.SysUserService;
import com.powernode.utils.AuthUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService{

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    /**
     * 分页查询
     * @param page
     * @param sysUser
     */
    @Override
    public void selectSysUserPage(Page<SysUser> page, SysUser sysUser) {
        sysUserMapper.selectPage(page, new LambdaQueryWrapper<SysUser>()
            .like(StrUtil.isNotBlank(sysUser.getUsername()), SysUser::getUsername, sysUser.getUsername())
                .orderByDesc(SysUser::getCreateTime)
        );
    }

    /**
     * 新增管理员用户
     * @param sysUser
     * @return
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public boolean save(SysUser sysUser) {
        // 1. 补充属性
        sysUser.setCreateTime(new Date());
        sysUser.setShopId(1L);

        String addUserId = AuthUtil.getLoginUserId();
        sysUser.setCreateUserId(Long.valueOf(addUserId));

        // 2. 密码加密
        sysUser.setPassword(bCryptPasswordEncoder.encode(sysUser.getPassword()));
        int isSuccess = sysUserMapper.insert(sysUser);

        if (isSuccess > 0) {

            Long userId = sysUser.getUserId();
            // 3. 新增管理员和角色的关系记录
            List<Long> roleIdList = sysUser.getRoleIdList();
            if (roleIdList != null && roleIdList.size() != 0) {

                ArrayList<SysUserRole> sysUserRoles = new ArrayList<>();

                // 4. 循环遍历role集合
                roleIdList.forEach(item -> {
                    // 5. 创建管理员与角色的关系
                    SysUserRole sysUserRole = new SysUserRole();
                    sysUserRole.setUserId(userId);
                    sysUserRole.setRoleId(item);

                    // 6. 尽量不要在循环中操作数据库，多条数据按照批量操作
                    sysUserRoles.add(sysUserRole);
                });

                // 7. 批量添加
                sysUserRoleService.saveBatch(sysUserRoles);
            }
        }

        return isSuccess > 0;
    }

    @Override
    public SysUser getById(Serializable id) {

        SysUser sysUser = sysUserMapper.selectById(id);
        if (sysUser == null) return null;

        sysUser.setPassword(null);

        List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectList(new LambdaQueryWrapper<SysUserRole>()
                .eq(SysUserRole::getUserId, id));

        if (!CollectionUtils.isEmpty(sysUserRoles) && sysUserRoles.size() != 0) {
            // 获取角色id集合
            List<Long> roleIdList = sysUserRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
            sysUser.setRoleIdList(roleIdList);
        }
        return sysUser;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public boolean updateById(SysUser sysUser) {

        // 1. 如果密码有值则修改密码否则不改变
        if(StrUtil.isNotBlank(sysUser.getPassword())) {
            // 2. 修改原来的密码
            sysUser.setPassword(bCryptPasswordEncoder.encode(sysUser.getPassword()));
        }

        // 3. 删除管理员原有的角色
        sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, sysUser.getUserId()));

        // 4. 删完再更新
        List<Long> roleIdList = sysUser.getRoleIdList();
        if (roleIdList != null && roleIdList.size() != 0) {
            ArrayList<SysUserRole> sysUserRoles = new ArrayList<>();

            // 4. 循环遍历role集合
            roleIdList.forEach(item -> {

                // 5. 创建管理员与角色的关系
                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setUserId(sysUser.getUserId());
                sysUserRole.setRoleId(item);

                // 6. 尽量不要在循环中操作数据库，多条数据按照批量操作
                sysUserRoles.add(sysUserRole);
            });

            // 7. 批量添加
            sysUserRoleService.saveBatch(sysUserRoles);
        }

        // 8. 注意修改MybatisPlus的更新策略，从not_null 变为not_empty, 这样字符串为空字符串的字段不会更新
        return sysUserMapper.updateById(sysUser) > 0;
    }
}
